package soo;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

/**
 * 数字验证码识别器（用于识别xxx系统的图片验证码）
 * 
 * 算法如下： 分析验证码图片结构，将其分隔成4个独立的数字图片，把四个独立的数字图片处理成单色位图。
 * 把单色位图转换为0、1数组，然后分别和0-9的字模进行匹配，得到图片上的数字信息。
 * 
 * @since JDK 1.5.0_8
 */
public class NumberVerCodeIdentifier2 {

	static {
		System.setProperty("com.sun.media.jai.disableMediaLib", "true");
	}

	// 字典
	private static String a0 = "001111000111111011100111110000111100001111000011110000111100001111000011111001110111111000111100";

	private static String a1 = "000011000001110000111100011011000100110000001100000011000000110000001100000011000000110000001100";

	private static String a2 = "001111000111111011100011110000110000001100000110000011100001110000111000011000001111111111111111";

	private static String a3 = "001111100111111111000011000000110001111000011110000001110000001111000011111001110111111000111100";

	private static String a4 = "000001100000111000001110000111100011011000110110011001101100011011111111111111110000011000000110";

	private static String a5 = "011111100111111001100000111000001111110011111110110001110000001111000011111001110111111000111100";// 前

	private static String a6 = "001111100111111101100011110000001101110011111110111001111100001111000011011000110111111000111100";

	private static String a7 = "111111111111111100000110000011000000110000011000000110000001100000111000001100000011000000110000";

	private static String a8 = "001111000111111011000011110000111100001101111110011111101100001111000011110000110111111000111100";

	public String recognize(BufferedImage image) {

		String result = "";

		BufferedImage newim[] = new BufferedImage[4];
		if (null == image) {
			throw new RuntimeException("iamage为null");
		}
		// 将图像分成四块，因为要处理的文件有四个数字。

		newim[0] = generateSingleColorBitMap(image.getSubimage(0, 5, 8, 12),
				"1");
		newim[1] = generateSingleColorBitMap(image.getSubimage(13, 7, 8, 12),
				"2");
		newim[2] = generateSingleColorBitMap(image.getSubimage(26, 5, 8, 12),
				"3");
		newim[3] = generateSingleColorBitMap(image.getSubimage(39, 7, 8, 12),
				"4");

		for (int k = 0; k < 4; k++) {
			int iw = newim[k].getWidth(null);
			int ih = newim[k].getHeight(null);

			StringBuffer numstr = new StringBuffer();
			// 因为是二值图像，这里的方法将像素读取出来的同时，转换为0，1的图像数组。
			for (int i = 0; i < ih; i++) {
				for (int j = 0; j < iw; j++) {

					int t = newim[k].getRGB(j, i);
					if (t == -1)
						numstr.append("0");
					else
						numstr.append("1");
					;

				}
			}
			// 得到像匹配的数字串。
			String aaaaa = numstr.toString();
			if (aaaaa.equals(a0)) {
				result = result + 0;
				// System.out.println(0);
			}

			if (aaaaa.equals(a1)) {
				result = result + 1;// System.out.println(1);
			}
			if (aaaaa.equals(a2)) {
				result = result + 2;// System.out.println(2);
			}
			if (aaaaa.equals(a3)) {
				result = result + 3;// System.out.println(3);
			}

			if (aaaaa.equals(a4)) {
				result = result + 4;// System.out.println(4);
			}
			if (aaaaa.equals(a5)) {
				result = result + 5;// System.out.println(4);
			}
			if (aaaaa.equals(a6)) {
				result = result + 6;// System.out.println(4);
			}
			if (aaaaa.equals(a7)) {
				result = result + 7;// System.out.println(7);
			}
			if (aaaaa.equals(a8)) {
				result = result + 8;// System.out.println(7);
			}
		}
		// System.out.println(result);
		return result;

	}

	/**
	 * 单色位图转换
	 * 
	 * @return
	 */
	private static BufferedImage generateSingleColorBitMap(Image colorImage,
			String tempFile) {
		BufferedImage image = new BufferedImage(8, 12,
				BufferedImage.TYPE_BYTE_GRAY);
		Graphics g = image.getGraphics();
		g.drawImage(colorImage, 0, 0, null);
		g.dispose();
		RenderedOp ro = JAI.create("binarize", image, new Double(100));
		BufferedImage bi = ro.getAsBufferedImage();

		
		File file = new File ("/home/jeffrey/Downloads/img/"+tempFile);
		String format = "JPEG";
		try {
			ImageIO.write(image,format,file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}//将图片保存为jpeg格式的文件file。也可以保存为jpg格式
		file = new File ("/home/jeffrey/Downloads/img/"+tempFile+tempFile);
		try {
			ImageIO.write(bi,format,file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}//将图片保存为jpeg格式的文件file。也可以保存为jpg格式
	
		return bi;
	}

	/**
	 * 测试
	 */
	public static void main(String args[]) {

		NumberVerCodeIdentifier2 nvi = new NumberVerCodeIdentifier2();

		String res = "";
		try {
			res = nvi.recognize(ImageIO.read(new File(
					"/home/jeffrey/Downloads/img/VerifyCodeCH.aspx.jpeg")));

			// res = nvi.recognize(ImageIO.read(new
			// URL("http://******.com/validationCode.jsp")));
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(res);
	}
}